Option Explicit On
Option Strict On

Imports ConnectionServer
Imports CObject
Imports System.Data.SqlClient
Imports System.Security.Cryptography
Imports System.IO
Imports System.Text
Imports Objects.Utility
Imports Objects.EmployeeInfo
Imports Microsoft.VisualBasic
Imports Objects.CMT

Namespace Security

    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' The SecurityObject class represents an item in the web site subject to security rules.
    ''' This can be a page or an item on that page.  It is also a method of creating the menu's.
    ''' </summary>
    ''' <remarks>
    ''' </remarks>
    ''' <history>
    ''' 	 	2/13/2004	Created
    ''' </history>
    ''' 
    Public Class SecurityObject

        Inherits CObject.CObject

        Private moRoles As ArrayList

        Protected Overrides Function ProcedureSigniture(ByVal peCommandType As CObject.CommandType) As String
            Select Case peCommandType
                Case CommandType.SQLSelect
                    Return " Select ObjectID, Name, Description,Href,Parent,Type,Target,ApplicationID,Sort From SEC_Objects "
                Case CommandType.SQLInsert
                    Return " EXEC dbo.SEC_InsertObject {Name},{Description},{Href},{Parent},{Type},{Target},{ApplicationID},{Sort}"
                Case CommandType.SQLUpdate
                    Return " EXEC dbo.SEC_UpdateObject {ObjectID},{Name},{Description},{Href},{Parent},{Type},{Target},{ApplicationID},{Sort}"
                Case CommandType.SQLDelete
                    Return " EXEC dbo.SEC_DeleteObject {ObjectID}"
                Case Else
                    Throw New Exception("Invalid CommandType")
            End Select
        End Function

        Public Overrides ReadOnly Property SourceDataBase() As ConnectionServer.Connection.SourceDataBase
            Get
                Return ConnectionServer.Connection.SourceDataBase.CMT
            End Get
        End Property

        Public Sub New()
            MyBase.New()
        End Sub

        Public Sub New(ByVal ObjectID As Integer)
            MyBase.New(ObjectID)
        End Sub

        Public Sub New(ByVal ObjectName As String)
            Dim loColl As New CCollection(New SecurityObject(), "Href='" & ObjectName & "'")

            mhtProperties = loColl.DataObject.Properties
        End Sub

        Public Overrides Function Clone() As CObject.CObject
            Return New SecurityObject
        End Function

        Public Overrides ReadOnly Property Key() As String
            Get
                Return "ObjectID"
            End Get
        End Property

#Region "Properties"

        ''' -----------------------------------------------------------------------------
        ''' <summary>
        ''' Target is specifically for a menu item.  It will control the Frame the 
        ''' menu will load the Href property into.
        ''' </summary>
        ''' <remarks>
        ''' </remarks>
        ''' <history>
        ''' 	 	2/13/2004	Created
        ''' </history>
        ''' 
        Public Property Target() As String
            Get
                If Not IsDBNull(GetProperty("Target")) Then
                    Return CStr(GetProperty("Target"))
                Else
                    Return ""
                End If

            End Get
            Set(ByVal Value As String)
                SetProperty("Target", Value)
            End Set
        End Property

        ''' -----------------------------------------------------------------------------
        ''' <summary>
        ''' Currently type is "internal" or "external".  This controls the menu items forecolor.
        ''' </summary>
        ''' <remarks>
        ''' </remarks>
        ''' <history>
        ''' 	 	2/13/2004	Created
        ''' </history>
        ''' 
        Public Property Type() As String
            Get
                If Not IsDBNull(GetProperty("Type")) Then
                    Return CStr(GetProperty("Type"))
                Else
                    Return ""
                End If
            End Get
            Set(ByVal Value As String)
                SetProperty("Type", Value)
            End Set
        End Property

        ''' -----------------------------------------------------------------------------
        ''' <summary>
        ''' Returns the parent ID of this secure object.
        ''' </summary>
        ''' <remarks>
        ''' </remarks>
        ''' <history>
        ''' 	 	2/13/2004	Created
        ''' </history>
        ''' 
        Public Property Parent() As Integer
            Get
                If IsDBNull(GetProperty("Parent")) Then
                    Return 0
                Else
                    Return CInt(GetProperty("Parent"))
                End If
            End Get
            Set(ByVal Value As Integer)
                SetProperty("Parent", Value)
            End Set
        End Property

        Public Property Sort() As Integer
            Get
                If IsDBNull(GetProperty("Sort")) Then
                    Return 0
                Else
                    Return CInt(GetProperty("Sort"))
                End If
            End Get
            Set(ByVal Value As Integer)
                SetProperty("Sort", Value)
            End Set
        End Property

        ''' -----------------------------------------------------------------------------
        ''' <summary>
        ''' Returns the parent object of this secure object
        ''' </summary>
        ''' <remarks>
        ''' </remarks>
        ''' <history>
        ''' 	 	2/13/2004	Created
        ''' </history>
        ''' 
        Public ReadOnly Property ParentObject() As SecurityObject
            Get
                Dim loColl As CCollection = New CCollection(New SecurityObject, "ObjectID = " & Parent.ToString)
                Return CType(loColl.DataObject, SecurityObject)
            End Get
        End Property

        ''' -----------------------------------------------------------------------------
        ''' <summary>
        ''' The Objects dependant on this object
        ''' </summary>
        ''' <value></value>
        ''' <remarks>
        ''' </remarks>
        ''' <history>
        ''' 	 	3/2/2005	Created
        ''' </history>
        ''' -----------------------------------------------------------------------------
        Public ReadOnly Property ChildObjects() As CDataTable
            Get
                Dim loColl As CCollection = New CCollection(New SecurityObject, "Parent = " & ObjectID.ToString)
                Return loColl.CDatatable
            End Get
        End Property

        ''' -----------------------------------------------------------------------------
        ''' <summary>
        ''' Specifically for menu items.  This is the page the menu_Onclick event will load.
        ''' </summary>
        ''' <remarks>
        ''' </remarks>
        ''' <history>
        ''' 	 	2/13/2004	Created
        ''' </history>
        ''' 
        Public Property Href() As String
            Get
                If Not IsDBNull(GetProperty("Href")) Then
                    Return CStr(GetProperty("Href"))
                Else
                    Return ""
                End If
            End Get
            Set(ByVal Value As String)
                SetProperty("Href", Value)
            End Set
        End Property

        ''' -----------------------------------------------------------------------------
        ''' <summary>
        ''' Specifically for menu items.  This is what the user sees in the text of the menu item.
        ''' </summary>
        ''' <remarks>
        ''' </remarks>
        ''' <history>
        ''' 	 	2/13/2004	Created
        ''' </history>
        ''' 
        Public Property Description() As String
            Get
                If Not IsDBNull(GetProperty("Description")) Then
                    Return CStr(GetProperty("Description"))
                Else
                    Return ""
                End If
            End Get
            Set(ByVal Value As String)
                SetProperty("Description", Value)
            End Set
        End Property

        ''' -----------------------------------------------------------------------------
        ''' <summary>
        ''' If this is a control on the page,  name is the controls name.  If this is a page itself,  name is the path of the page.
        ''' </summary>
        ''' <remarks>
        ''' </remarks>
        ''' <history>
        ''' 	 	2/13/2004	Created
        ''' </history>
        ''' 
        Public Property Name() As String
            Get
                If Not IsDBNull(GetProperty("Name")) Then
                    Return CStr(GetProperty("Name"))
                Else
                    Return ""
                End If
            End Get
            Set(ByVal Value As String)
                SetProperty("Name", Value)
            End Set
        End Property

        ''' -----------------------------------------------------------------------------
        ''' <summary>
        ''' The unique ID for each secure object
        ''' </summary>
        ''' <remarks>
        ''' </remarks>
        ''' <history>
        ''' 	 	2/13/2004	Created
        ''' </history>
        ''' 
        Public Property ObjectID() As Integer
            Get
                Return CInt(GetProperty("ObjectID"))
            End Get
            Set(ByVal Value As Integer)
                SetProperty("ObjectID", Value)
            End Set
        End Property

        ''' -----------------------------------------------------------------------------
        ''' <summary>
        ''' An arraylist of the Role objects with security for this object
        ''' </summary>
        ''' <remarks>
        ''' </remarks>
        ''' <history>
        ''' 	 	2/13/2004	Created
        ''' </history>
        ''' 
        Public ReadOnly Property Roles() As CDataTable
            Get
                Dim loRoleIDs As ArrayList = RoleIDs
                Dim liRoleID As Integer
                Dim lsRoles As String = ""
                For Each liRoleID In loRoleIDs
                    lsRoles += "," & liRoleID.ToString
                Next
                If lsRoles.Length = 0 Then Return Nothing
                lsRoles = lsRoles.Substring(1)
                Dim loColl As CCollection = New CCollection(New Group, "GroupID in (" & lsRoles & ")", "")
                If loColl.CDatatable Is Nothing Then
                    Return New CDataTable
                Else
                    Return loColl.CDatatable
                End If

            End Get
        End Property

        ''' -----------------------------------------------------------------------------
        ''' <summary>
        ''' The ID Of the application this object is associated with 
        ''' </summary>
        ''' <value></value>
        ''' <remarks>
        ''' </remarks>
        ''' <history>
        ''' 	 	3/2/2005	Created
        ''' </history>
        ''' -----------------------------------------------------------------------------
        Public Property ApplicationID() As Integer
            Get
                Return CastToInteger(GetProperty("ApplicationID"))
            End Get
            Set(ByVal Value As Integer)
                SetProperty("ApplicationID", Value)
            End Set
        End Property

        ''' -----------------------------------------------------------------------------
        ''' <summary>
        ''' The list of roles with security for this object
        ''' </summary>
        ''' <remarks>
        ''' </remarks>
        ''' <history>
        ''' 	 	2/13/2004	Created
        ''' </history> 
        Public Property RoleIDs() As ArrayList
            Get
                If moRoles Is Nothing Then
                    Dim loConnServer As ConnectionServer.Connection = New ConnectionServer.Connection
                    Dim loConn As SqlConnection = loConnServer.GetConnection(ConnectionServer.Connection.SourceDataBase.CMT)
                    Dim loCmd As SqlCommand
                    Dim loAL As ArrayList
                    Try
                        loCmd = New SqlCommand("EXEC SEC_GetRolesByObjectID " & ObjectID, loConn)
                        loAL = New ArrayList
                        Dim loReader As SqlDataReader = loCmd.ExecuteReader
                        Do While loReader.Read
                            loAL.Add(loReader(0))
                        Loop
                    Finally
                        loConn.Close()
                    End Try

                    Return loAL
                Else
                    Return moRoles
                End If
            End Get
            Set(ByVal value As ArrayList)
                moRoles = value
            End Set
        End Property

#End Region

#Region "Methods"

        Public Sub RemoveRole(ByVal piRoleID As Integer)
            Dim loConn As Connection = New Connection(Connection.SourceDataBase.CMT)
            Using loComm As SqlCommand = loConn.Command("Delete SEC_RolePermissions WHERE RoleID= " & piRoleID.ToString & " AND ObjectID=" & ObjectID.ToString)
                loComm.ExecuteNonQuery()
                loComm.Connection.Close()
            End Using
        End Sub

        Public Sub AddRole(ByVal piRoleID As Integer)
            Dim loConn As Connection = New Connection(Connection.SourceDataBase.CMT)
            Using loComm As SqlCommand = loConn.Command("EXEC SEC_InsertRoleObject " & piRoleID.ToString & "," & ObjectID.ToString)
                loComm.ExecuteNonQuery()
                loComm.Connection.Close()
            End Using
        End Sub

        ''' -----------------------------------------------------------------------------
        ''' <summary>
        ''' Saves the current RoleID's to the database
        ''' </summary>
        ''' <remarks>
        ''' </remarks>
        ''' <history>
        ''' 	 	2/13/2004	Created
        ''' </history>
        Public Sub SaveMenuRoles(ByVal loTran As SqlTransaction, ByVal loConn As SqlConnection)
            Dim liRoleID As Integer
            Dim loComm As SqlCommand

            loComm = New SqlCommand("EXEC SEC_ClearObjectRoles " & ObjectID.ToString, loConn, loTran)
            loComm.ExecuteNonQuery()

            If Not moRoles Is Nothing Then
                For Each liRoleID In moRoles
                    loComm = New SqlCommand("EXEC SEC_InsertRoleObject " & liRoleID.ToString & "," & ObjectID.ToString, loConn, loTran)
                    loComm.ExecuteNonQuery()
                Next
            End If

        End Sub


        ''' -----------------------------------------------------------------------------
        ''' <summary>
        ''' Saves the current RoleID's to the database
        ''' </summary>
        ''' <remarks>
        ''' </remarks>
        ''' <history>
        ''' 	 	2/13/2004	Created
        ''' </history>
        Public Sub SaveMenuRoles()
            Dim liRoleID As Integer
            Dim loComm As SqlCommand
            Dim loConnServer As ConnectionServer.Connection = New ConnectionServer.Connection
            Dim loConn As SqlConnection = loConnServer.GetConnection(ConnectionServer.Connection.SourceDataBase.CMT)
            Dim loTran As SqlTransaction = loConn.BeginTransaction

            loComm = New SqlCommand("EXEC SEC_ClearObjectRoles " & ObjectID.ToString, loConn, loTran)
            loComm.ExecuteNonQuery()

            If Not moRoles Is Nothing Then
                For Each liRoleID In moRoles
                    loComm = New SqlCommand("EXEC SEC_InsertRoleObject " & liRoleID.ToString & "," & ObjectID.ToString, loConn, loTran)
                    loComm.ExecuteNonQuery()
                Next
            End If
            loTran.Commit()
        End Sub

        Public Function UserHasPermission(ByVal psGUI As String) As Boolean

            Dim liAns As Integer = 0
            Using loConn As SqlConnection = New ConnectionServer.Connection(ConnectionServer.Connection.SourceDataBase.CMT).Connection
                Dim lsSQL As String = "EXEC SEC_UserHasPermission " & ObjectID.ToString & ",'" & psGUI & "'"
                Dim loComm As SqlCommand = New SqlCommand(lsSQL, loConn)
                liAns = CInt(loComm.ExecuteScalar)
                loConn.Close()
                loConn.Dispose()
            End Using

            If liAns > 0 Then
                Return True
            Else
                Return False
            End If

        End Function

        ''' <summary>
        ''' Get list of objects
        ''' </summary>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Function GetObjectList() As DataTable
            Using lobjConnection As ConnectionServer.Connection = New ConnectionServer.Connection
                Dim lobjConn As SqlConnection = lobjConnection.GetConnection(ConnectionServer.Connection.SourceDataBase.CMT)
                Dim lobjComm As SqlCommand = New SqlCommand("SELECT S.ObjectID as ObjectID,S.Name as Name,S.Description as Description,S.Parent as Parent,S.Href as Href,P.Name as ParentName,S.Type as Type,S.Target as Target,S.Sort as Sort FROM  SEC_Objects S left join SEC_Objects P on S.Parent = P.ObjectID", lobjConn)
                Dim lobjADP As SqlDataAdapter = New SqlDataAdapter(lobjComm)
                Dim lobjDataTable As DataTable = New DataTable
                lobjADP.Fill(lobjDataTable)
                lobjConn.Close()
                Return lobjDataTable
            End Using
        End Function

        Public Function GetMembersData() As DataTable
            Using loConn As Connection = New Connection(Connection.SourceDataBase.CMT)
                Dim lsSQL As String = "EXEC SEC_GetMembersData " & ObjectID.ToString
                Return loConn.GetDataTable(lsSQL)
            End Using
        End Function

#End Region

    End Class

    Public Class SecurityUserRight
        Inherits CObject.CObject

        Public Overrides Function Clone() As CObject.CObject
            Return New SecurityUserRight
        End Function

        Public Overrides ReadOnly Property Key() As String
            Get
                Return "RightsID"
            End Get
        End Property

        Public Sub New()

        End Sub

        Public Sub New(ByVal piRightsID As Integer)
            MyBase.New(piRightsID)

        End Sub

        Protected Overrides Function ProcedureSigniture(ByVal peCommandType As CObject.CommandType) As String
            Select Case peCommandType
                Case CommandType.SQLSelect
                    Return "SELECT RightsID,GUI,EXCEPTION,EXPIRATION_DT,GROUPS,GroupID FROM SEC_USER_RIGHTS"

                Case CommandType.SQLInsert, CommandType.SQLUpdate
                    Return "EXEC GSR_SecUserRights_UPDATE  {RightsID},{GUI},{EXCEPTION},{EXPIRATION_DT},{GroupID},{Groups}"

                Case CommandType.SQLDelete
                    Return "EXEC GSR_SecUserRights_DELETE {RightsID}"

                Case Else
                    Throw New Exception("Invalid CommandType")
            End Select
        End Function

        Public Overrides ReadOnly Property SourceDataBase() As ConnectionServer.Connection.SourceDataBase
            Get
                Return Connection.SourceDataBase.CMT
            End Get
        End Property

#Region "Properties"

        Public ReadOnly Property ID() As Integer
            Get
                Return CastToInteger(GetProperty("RightsID"))
            End Get
        End Property

        Public Property GUI() As String
            Get
                Return CastToString(GetProperty("GUI"))
            End Get
            Set(ByVal value As String)
                SetProperty("GUI", value)
            End Set
        End Property

        Public Property Groups() As String
            Get
                Return CastToString(GetProperty("GROUPS"))
            End Get
            Set(ByVal value As String)
                SetProperty("GROUPS", value)
            End Set
        End Property

        Public ReadOnly Property RoleObj() As Role
            Get
                Return New Role(GroupID)
            End Get
        End Property

        Public Property Exception() As Boolean
            Get
                Return CastToBoolean(GetProperty("EXCEPTION"))
            End Get
            Set(ByVal value As Boolean)
                SetProperty("EXCEPTION", value)
            End Set
        End Property

        Public Property ExpirationDate() As Date
            Get
                Return CastToDate(GetProperty("EXPIRATION_DT"))
            End Get
            Set(ByVal value As Date)
                SetProperty("EXPIRATION_DT", value)
            End Set
        End Property

        Public Property GroupID() As Integer
            Get
                Return CastToInteger(GetProperty("GroupID"))
            End Get
            Set(ByVal value As Integer)
                SetProperty("GroupID", value)
            End Set
        End Property

#End Region

#Region "Methods"

#End Region

    End Class

    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' Security Helper Class - will have misceleneous Database Calls
    ''' </summary>
    ''' <remarks>
    ''' </remarks>
    ''' <history>
    ''' 		03/28/2007	Created
    ''' </history>
    ''' 

    Public Class SecurityUtility

        Public Function GetSecObjects() As DataSet


            Dim loRawTable As DataTable
            Using loConnServer As ConnectionServer.Connection = New ConnectionServer.Connection(ConnectionServer.Connection.SourceDataBase.CMT)
                loRawTable = loConnServer.GetDataTable("EXEC GET_SecObjects")
            End Using
            Dim loDataSet As DataSet = New DataSet
            Dim loTable As DataTable
            Dim llTableCount As Integer
            Dim loRelation As DataRelation
            Dim loRow As DataRow

            Dim loTableMaster As DataTable



            For Each ldrRaw As DataRow In loRawTable.Rows

                If loDataSet.Tables.IndexOf(ldrRaw("Parent").ToString) = -1 Then
                    Dim loNewTable As DataTable = New DataTable(ldrRaw("Parent").ToString)
                    loNewTable.Columns.AddRange(New DataColumn() _
                            {New DataColumn("ObjectID"), New DataColumn("Name"), _
                            New DataColumn("Description"), New DataColumn("HRef"), _
                            New DataColumn("Parent"), New DataColumn("Type"), _
                            New DataColumn("Target"), New DataColumn("ApplicationID"), _
                            New DataColumn("Sort")})
                    loDataSet.Tables.Add(loNewTable)
                End If
                loTable = loDataSet.Tables(ldrRaw("Parent").ToString)
                Dim ldrNew As DataRow = loTable.NewRow
                ldrNew.ItemArray = ldrRaw.ItemArray
                loTable.Rows.Add(ldrNew)


            Next

            For Each loTableMaster In loDataSet.Tables
                loTableMaster.TableName = llTableCount.ToString
                llTableCount += 1
                For Each loRow In loTableMaster.Rows
                    For Each loTable In loDataSet.Tables
                        If loTable.TableName <> loTableMaster.TableName Then
                            If loTable.Rows.Count > 0 Then
                                If Not IsDBNull(loTable.Rows(0)("Parent")) Then
                                    If loRow("ObjectID").ToString = loTable.Rows(0)("Parent").ToString Then
                                        loRelation = New DataRelation(loRow("Name").ToString, loTableMaster.Columns("ObjectID"), loTable.Columns("Parent"))
                                        Try
                                            loDataSet.Relations.Add(loRelation)
                                        Catch ex As Exception
                                        End Try
                                    End If
                                End If
                            End If
                        End If
                    Next
                Next
            Next
            Return loDataSet


        End Function

        Public Function SecurityLookup(ByVal psCurrenUserGUI As String, ByVal psWhere As String, ByVal pbIsApplicationEmpty As Boolean, Optional ByVal psSort As String = "ApplicationName,Groups,Last_Name") As DataTable
            Dim loDataTable As DataTable = New DataTable
            Dim loConnection As Connection = New Connection(Connection.SourceDataBase.CMT)
            Dim lsAppList As String = "0"

            Dim lsSQL As String = "EXEC SEC_SecurityLookup '" & psCurrenUserGUI & "','" & psWhere & "',"
            If pbIsApplicationEmpty Then
                Dim loRow As DataRow
                Dim loDT As DataTable = SecureApplicationsForSearch(psCurrenUserGUI)
                For Each loRow In loDT.Rows
                    lsAppList &= "," & loRow("ApplicationID").ToString
                Next
                lsSQL &= "1,'" & psSort & "','" & lsAppList & "'"
            Else
                lsSQL &= "0,'" & psSort & "','" & lsAppList & "'"
            End If

            loDataTable = loConnection.GetDataTable(lsSQL)

            loConnection.Connection.Close()

            Return loDataTable
        End Function

        ''' <summary>
        ''' Returns the Applications the user has ability to search feature.
        ''' </summary>
        ''' <param name="psCurrenUserGUI"></param>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Function SecureApplicationsForSearch(ByVal psCurrenUserGUI As String) As DataTable

            Dim loDataTable As DataTable = New DataTable
            Dim loConnection As Connection = New Connection(Connection.SourceDataBase.CMT)


            Dim lsSQL As String = "EXEC SEC_SecureApplicationsForSearch '" & psCurrenUserGUI & "'"
            loDataTable = loConnection.GetDataTable(lsSQL)

            loConnection.Connection.Close()

            Return loDataTable
        End Function

        ''' <summary>
        ''' Returns a list of distinct role names
        ''' </summary>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Function GetRoleNames(ByVal psGUI As String) As DataTable

            Dim loDataTable As DataTable = New DataTable
            Dim loConnection As Connection = New Connection(Connection.SourceDataBase.CMT)

            Dim lsSQL As String = "EXEC SEC_GetRoleNames '" & psGUI & "'"
            loDataTable = loConnection.GetDataTable(lsSQL)

            loConnection.Connection.Close()

            Return loDataTable
        End Function

        ''' <summary>
        ''' Returns the Security Request Details (that are reviewed by the Sec Admin)
        ''' </summary>
        ''' <param name="psWhere"></param>
        ''' <param name="psSort"></param>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Function SecurityRequestDetails(ByVal psWhere As String, ByVal psSort As String) As DataTable

            Dim loDataTable As DataTable = New DataTable
            Dim loConnection As Connection = New Connection(Connection.SourceDataBase.CMT)

            Dim lsSQL As String = "EXEC SEC_SecurityRequestDetails '" & psWhere & "','" & psSort & "'"
            loDataTable = loConnection.GetDataTable(lsSQL)

            loConnection.Connection.Close()

            Return loDataTable

        End Function
       
    End Class

End Namespace
